PS: 今天我們要重回狗狗迷因了!!
makefile
編譯的方法 (這邊的makefile用小寫跟cmake編出來的做區分)cmake
編出 Makefile
cmake
# ========= Project =========
TARGET := app
SRC_DIR := src
INC_DIR := inc
BUILD_DIR := build
SRCS := $(wildcard $(SRC_DIR)/*.c)
OBJS := $(patsubst $(SRC_DIR)/%.c,$(BUILD_DIR)/%.o,$(SRCS))
DEPS := $(OBJS:.o=.d)
# ========= Toolchain & Flags =========
CC ?= gcc
# Preprocess flags (-I/-D), compile flags, link flags
CPPFLAGS := -I$(INC_DIR) -DAPP_VERSION=\"1.0.0\"
CFLAGS := -O2 -Wall -Wextra -Wpedantic
LDFLAGS :=
# DEBUG=1 to enable debug build
ifeq ($(DEBUG),1)
CFLAGS := -O0 -g3 -Wall -Wextra -Wpedantic
endif
# Auto dependencies (.d files)
DEPFLAGS := -MMD -MP
# ========= Rules =========
.PHONY: all clean run install uninstall
all: $(BUILD_DIR)/$(TARGET)
$(BUILD_DIR)/$(TARGET): $(OBJS) | $(BUILD_DIR)
$(CC) $(OBJS) -o $@ $(LDFLAGS)
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c | $(BUILD_DIR)
$(CC) $(CPPFLAGS) $(CFLAGS) $(DEPFLAGS) -c $< -o $@
$(BUILD_DIR):
@mkdir -p $@
run: all
./$(BUILD_DIR)/$(TARGET)
# Install to ./dist by default (override with PREFIX=/usr/local)
PREFIX ?= $(CURDIR)/dist
install: all
@mkdir -p $(PREFIX)/bin
@mkdir -p $(PREFIX)/include
@cp -f $(BUILD_DIR)/$(TARGET) $(PREFIX)/bin/
@cp -rf $(INC_DIR)/. $(PREFIX)/include/
uninstall:
@rm -f $(PREFIX)/bin/$(TARGET)
@rm -rf $(PREFIX)/include
clean:
@rm -rf $(BUILD_DIR) dist
# Include auto-generated dependency files
-include $(DEPS)
cmake_minimum_required(VERSION 3.21)
project(C_PROJ VERSION 1.0.0 LANGUAGES C)
# Export compile_commands.json for clangd/clang-tidy
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# C standard
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
# Library from src/dog_meme.c
add_library(dog_meme STATIC
src/dog_meme.c
)
target_include_directories(dog_meme
PUBLIC
${CMAKE_SOURCE_DIR}/inc
)
# Executable from src/main.c
add_executable(app
src/main.c
)
target_link_libraries(app PRIVATE dog_meme)
# Target-scoped warnings/defines/includes
target_compile_options(app PRIVATE -Wall -Wextra -Wpedantic)
target_compile_definitions(app PRIVATE APP_VERSION="1.0.0")
target_include_directories(app PRIVATE ${CMAKE_SOURCE_DIR}/inc)
# Install rules
install(TARGETS app RUNTIME DESTINATION bin)
install(DIRECTORY inc/ DESTINATION include)
前面幾個章節有提到,其實就只是把makefile 準備好,然後下command 到專案的terminal 就可以直接編譯出執行檔
make
除了make執行編譯之外,還有幾個自己列舉的 .PHONY: all clean run install uninstall
也可以透過下面的指令去出指定的動作
cd C_proj
make # 編譯到 build/app
make run # 執行
make clean # 清理
make install # 安裝到 ./dist(或 PREFIX=/usr/local)
Cmake 執行的話,主要會分成兩個步驟:
cd C_proj<專案根目錄>
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug # 產生Makefilie
cmake --build build -j
./build/app #執行程式 --> 產生狗狗迷因圖
# 安裝
cmake --install build --prefix ./dist